/* * @Author: hhy * @Date: 2019-02-27 10:37:38 * @Last Modified by: hhy * @Last
Modified time: 2019-06-24 14:10:15 * @文件说明: oss上传文件 */
<template>
  <div class="uploadFlex">
    <div
      style="position: relative"
      v-for="(item, index) in imgList"
      :key="index"
    >
      <img
        v-if="item.fileSuffix == 'pdf'"
        class="mr20"
        style="width: 100px; height: 100px; border-radius: 10px"
        :src="pdf"
        alt=""
      />
      <img
        v-if="item.fileSuffix == 'zip'"
        class="mr20"
        style="width: 100px; height: 100px; border-radius: 10px"
        :src="zip"
        alt=""
      />
      <video
        controls
        v-if="item.fileType == 'mp4'"
        class="mr20"
        style="width: 100px; height: 100px; border-radius: 10px"
        :src="item.filePath"
      ></video>
      <img
        v-if="
          item.fileSuffix != 'pdf' &&
          item.fileSuffix != 'zip' &&
          item.fileType != 'mp4'
        "
        class="mr20"
        style="width: 100px; height: 100px; border-radius: 10px"
        :src="item.filePath"
        alt=""
      />
      <div class="close" @click="removeImg(index)">
        <el-icon><Close /></el-icon>
      </div>
    </div>
    <div v-if="imgList.length == 0 || allowMultiple" class="h-oss full bjz-oss">
      <div class="demo-progress" v-if="progress">
        <el-progress
          :percentage="percentage"
          :text-inside="true"
          :stroke-width="16"
          style="width: 100%"
        >
        </el-progress>
      </div>
      <h-bgi :bgi="upimg" w="100" h="100">
        <el-upload
          :http-request="ossUpload"
          :before-upload="ossBeforeUpload"
          :on-success="ossUploadSuccess"
          :on-error="ossUploadError"
          :show-file-list="true"
          :multiple="multiple"
          :accept="accept"
          v-model:file-list="fileList"
          action
          class="drag-upload"
          :drag="type === 'drag'"
          :list-type="type === 'picture-card' ? 'picture-card' : ''"
        >
          <template v-if="type">
            <h-bgi v-if="ImgUrl" :bgi="ImgUrl" h="100%" w="100%">
              <span class="bgi-hover hover white">{{
                urls ? "上传图片" : "重新上传"
              }}</span>
            </h-bgi>
            <template v-else-if="type === 'drag'">
              <el-icon><upload-filled /></el-icon>
              <div class="el-upload__text">
                将文件拖到此处，或
                <em>点击上传</em>
              </div>
            </template>
            <el-icon v-else><plus /></el-icon>
          </template>
          <slot>
            <el-button
              v-if="load"
              :loading="load"
              type="primary"
              class="Uploading"
              >上传中</el-button
            >
            <el-button
              v-else
              type="primary"
              class="hoverDiv"
              :class="[
                { 'hover-show': HoverType },
                { 'hover-show1': HoverType1 },
              ]"
            >
              点击上传
              <p class="wi" v-if="NameTips != ''">{{ NameTips }}</p>
            </el-button>
          </slot>
        </el-upload>
      </h-bgi>
    </div>
  </div>
</template>

<script>
import { baseMsg } from "@/utils/utils";
import { defineComponent, toRefs, reactive, ref, watch } from "vue";
import { UploadFile } from "@/api/login";
import upimg from "@/assets/icon-upload.png";
import zip from "@/assets/icon-zip.png";
import pdf from "@/assets/icon-pdf.png";
export default defineComponent({
  props: {
    // 是否权限不足情况,
    width: {
      type: Number,
      default: 100,
    },
    HoverType: {
      type: Boolean,
      default: false,
    },
    HoverType1: {
      type: Boolean,
      default: false,
    },
    // 上传图片UI类型：'drag'、'picture-card'、''
    NameTips: {
      type: String,
      default: "",
    },
    type: {
      type: String,
      default: "",
    },
    full: {
      type: Boolean,
      default: true,
    },
    multiple: {
      type: Boolean,
      default: false,
    },
    // 是否允许多张上传
    allowMultiple: {
      type: Boolean,
      default: false,
    },
    disabled: {
      type: Boolean,
      default: false,
    },
    urls: {
      type: Boolean,
      default: false,
    },
    url: {
      type: String,
      default: "",
    },
    accept: {
      type: Array,
      default: [],
    },
    previewList: {
      type: Array,
      default: [],
    },
    noacceptmsg: {
      type: String,
      default: "",
    },
    size: {
      type: String || Number,
      default: "10",
    },
    nowIndex: {
      type: Number,
      default: 0,
    },
  },
  emits: ["uploading", "success", "error", "remove"],
  setup(props, context) {
    const state = reactive({
      upimg,
      pdf,
      zip,
      load: false,
      postfix: ".png",
      OriginalFile: null,
      ImgUrl: props.url,
      percentage: 0,
      progress: false,
      progressnum: 0,
      Timeout: null,
      imgList: props.previewList,
    });
    watch(
      () => props.url,
      (val) => {
        state.ImgUrl = val;
      }
    );
    watch(
      () => props.previewList,
      (val) => {
        state.imgList = val;
      },
      { deep: true }
    );

    // 图片上传前处理
    const ossBeforeUpload = (file) => {
      state.progressnum = 0;
      const index = file.name.lastIndexOf(".");
      const isAccept = props.accept.indexOf(file.name.substr(index));

      if (isAccept < 0 && props.accept != []) {
        baseMsg(props.noacceptmsg || `请上传${props.accept}等格式`, false);
        return false;
      }

      // 大小 5M
      const isSize = file.size / 1024 / 1024;
      state.progress = true;

      state.Timeout = setInterval(() => {
        if (state.percentage < 95) {
          if (isSize > 1) {
            state.progressnum = state.progressnum + 0.01;
            state.percentage = Math.floor((state.progressnum / isSize) * 100);
          } else {
            state.progressnum = state.progressnum + 10;
            state.percentage = state.progressnum;
          }
        } else {
          clearInterval(state.Timeout);
          state.Timeout = null;
        }
      }, 100);
      if (isSize > Number(props.size)) {
        baseMsg(`请上传${props.size}M以下的文件`, false);
        return false;
      }
    };
    // 图片上传中
    const ossUpload = async (option) => {
      const file = option.file;
      state.load = true;
      const filedata = new FormData();

      filedata.append("files", file);
      filedata.append("file", file.name);

      UploadFile(filedata)
        .then((res) => {
          state.progress = false;
          clearInterval(state.Timeout);
          state.Timeout = null;
          state.progressnum = 0;
          if (res.code == 4202 || res.code == 4201) {
            ossUploadSuccess(res.data);
          } else {
            ossUploadError(res.data);
          }
        })
        .catch((err) => {
          ossUploadError({
            key: err.data,
          });
          state.progress = false;
          clearInterval(state.Timeout);
          state.Timeout = null;
        });
    };

    // 图片上传完成
    const ossUploadSuccess = (res) => {
      if (res) {
        state.load = false;
        baseMsg("文件上传完成");
        context.emit("success", res[0], props.nowIndex);
      }
    };
    // 图片上传失败
    const ossUploadError = (err) => {
      state.load = false;
      baseMsg("上传失败", false);
      context.emit("error", err);
    };
    // 上传文件删除
    const removeImg = (index) => {
      context.emit("remove", index, props.nowIndex);
    };

    return {
      ...toRefs(state),
      ossBeforeUpload,
      ossUpload,
      ossUploadSuccess,
      removeImg,
    };
  },

  methods: {},
});
</script>
<style lang="scss">
.bjz-oss {
  width: 100%;
  height: 100%;
  position: relative;
  display: inline-block;
  .drag-upload,
  .el-upload {
    width: 100%;
    height: 100%;
  }
  .demo-progress {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 100%;
    height: 20px;
    min-width: 100px;
    background-color: rgba(255, 255, 255, 1) !important;
    .percentage-value {
      color: #0076ff;
      font-size: 15px;
    }
    .el-progress-bar__outer {
      background-color: rgba(102, 151, 207, 0.4);
    }
    .percentage-label {
      display: block;
      color: #6697cf;
      font-size: 10px;
    }
  }
  .hoverDiv {
    width: 100% !important;
    height: 100%;
    position: absolute;
    top: 0;
    left: 0;
    bottom: 0;
    background-color: rgba(0, 0, 0, 0.5) !important;
    opacity: 0;
    color: $common-theme-color;
  }
  .Uploading {
    position: absolute;
    top: 0;
    left: 0;
    width: 100% !important;
    height: 100% !important;
    bottom: 0;
    background-color: rgba(0, 0, 0, 0.5) !important;
  }
  .hoverDiv:hover {
    opacity: 1;
  }
  .hover-show {
    display: none;
    opacity: 0;
  }
  .hover-show1 {
    display: block;
    opacity: 1 !important;
    border: 0;
    background-color: rgba(0, 0, 0, 0) !important;
  }
  .drag-upload {
    .el-upload {
      display: block;
      .el-upload-dragger {
        // height: 90px;
        height: 193px;
        @include flex-c($fd: column);
        .el-icon-upload {
          margin: 0 0 10px;
          // margin: 10px 0 0 10px;
          font-size: 50px;
          line-height: initial;
        }
        .el-upload__text {
          line-height: initial;
        }
      }
    }
  }
  .disabled {
    position: absolute;
    top: 0;
    bottom: 0;
    right: 0;
    left: 0;
    background-color: #f5f7fa;

    cursor: not-allowed;
    opacity: 0.6;
  }
  .wi {
    color: rgba(255, 255, 255, 0.8);
    font-size: 10px;
    margin-top: 10px;
    display: none;
  }
}
.uploadFlex {
  display: flex;
  .close {
    width: 15px;
    height: 15px;
    border-radius: 50%;
    background-color: #fff;
    position: absolute;
    top: 2px;
    right: 22px;
    display: flex;
    justify-content: center;
  }
}
</style>
